/*
 * Copyright (c) 2023-2024 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.tenant.api.utils;

import jakarta.servlet.http.HttpServletRequest;

/**
 * URL处理器
 *
 * @author zeng
 */
public class URLProcessor {

  /**
   * 从HTTP请求中提取主机地址。
   *
   * <p>该方法的目的是从完整的URL中获取主机名和端口号。它适用于处理包括域名和IP地址在内的各种主机格式。 例如，从以下URL中提取主机：
   *
   * <ul>
   *   <li>{@code http://www.example.com/api/v1/users} -> www.example.com
   *   <li>{@code https://www.example.com:8080/api/v1/users} -> www.example.com:8080
   *   <li>{@code http://127.0.0.1:8080/api/v1/users} -> 127.0.0.1:8080
   * </ul>
   *
   * @param request HTTP请求对象，从中提取主机信息。
   * @return 返回提取的主机地址，可能包括端口号。
   */
  public static String extractDomain(HttpServletRequest request) {

    // 初始化StringBuilder以避免同步带来的性能开销。
    StringBuilder urlBuilder = new StringBuilder(request.getRequestURL().toString());
    String uri = request.getRequestURI();
    String scheme = request.getScheme();

    // 验证urlBuilder的长度，以避免StringIndexOutOfBoundsException。
    // 确保scheme.length()+3不会超出urlBuilder的长度。
    int schemeLength = scheme.length() + 3;
    if (schemeLength >= urlBuilder.length()) {
      // 如果scheme加上3大于或等于url的长度，说明URL格式不正确，可以考虑记录日志或抛出异常。
      // 这里选择返回空字符串，具体处理逻辑应根据实际需求确定。
      return "";
    }

    // 删除包括请求URI的部分。
    // 先检查是否越界，以避免StringIndexOutOfBoundsException。
    int uriStartIndex = urlBuilder.length() - uri.length();
    if (uriStartIndex >= 0) {
      urlBuilder.delete(uriStartIndex, urlBuilder.length());
    }

    // 删除协议部分。由于前面的检查，这里不会抛出StringIndexOutOfBoundsException。
    urlBuilder.delete(0, schemeLength);

    // 返回处理后的URL。
    return urlBuilder.toString();
  }
}
